ทดสอบว่า Server สามารถรับ Load ได้แค่ไหนด้วย Distributed Load Testing on AWS
สวัสดีครับ ต้าครับ
โดยปกติแล้ว Tool ที่ใช้งานในการ Load Test ที่เราเห็นบ่อยๆจะเป็น JMeter, Gatling หรือ AB (Apache Bench) ที่เราเห็นกัน แต่วันนี้เราจะมาลองทำ Load Testing ด้วย AWS Service กันครับ
โดยเนื้อหาในบทความนี้จะเป็นการเอาข้อมูลมาจากเว็บไซต์ต่อไปนี้
หรือหากใครที่อยากจะลองทำตามแบบเป็นคลิปวิดีโอก็มีคนลองทำแล้วเหมือนกันครับ
Load Testing คืออะไร
Load Testing คือ การทดสอบประสิทธิภาพการทำงานของระบบภายใต้ปริมาณการใช้งานที่กำหนด โดยเป้าหมายหลักคือการค้นหาปัญหาคอขวด (bottleneck) และปัญหาด้านประสิทธิภาพของระบบ เช่น หน่วยความจำรั่วไหล (memory leak) ปัญหาคุณภาพของโค้ด (code quality) หรือปัญหาการจัดการหน่วยความจำ (memory management) นอกจากนี้ยังช่วยกำหนดขีดจำกัด (limit) ของการใช้งานระบบ เช่น จำนวนผู้ใช้สูงสุดที่ระบบสามารถรองรับได้
สรุปสั้นคือ การทดสอบว่า Sever เราสามารถรองรับงานต่างๆได้มากแค่ไหนครับ
สิ่งที่ต้องเตรียมก่อนเริ่มทำ
- Demo website ที่เราจะทำการทดสอบ (โดยในบทความนี้ผมจะใช้เว็บไซต์ test.php ในการทดสอบ ซึ่งหากจะลองทำตาม สามารถดูได้จากบทความต่อไปนี้ครับ > วิธีติดตั้ง PHP 8.2 และ Apache ใน Amazon Linux 2023 บน EC2 | DevelopersIO)
1.1. instance type ที่ผมใช้คือ t2.micro - AWS Account
- AWS User ที่มีสิทธิการใช้ CloudFormation
- VPC ที่เตรียมไว้สำหรับ CloudFormation Stack (ที่ผมทำในบทความนี้คือมี 2 Public subnet, 2 Private subnet)
ค่าใช้จ่ายที่จะเกิดขึ้น
ไม่มีค่าใช้จ่ายในการใช้ Solution ต่อไปนี้ แต่จะมีการเกิดค่าใช้จ่ายจริงตาม AWS Service ที่ถูกใช้งาน
แต่เนื่องจากโครงสร้างที่จำทำต่อไปนี้เป็น Serverless ซะส่วนใหญ่ ทำให้แทบจะไม่มีค่าใช้จ่ายเกิดขึ้นหากเราไม่ได้ใช้งาน
หรือสามารถดูรายละเอียดได้ที่ลิ้งค์ด้านล่างนี้
Cost - Distributed Load Testing on AWS
เริ่มลงมือทำ
สิ่งที่เราจะทำการคือการสร้าง Web Application สำหรับทำการทดสอบ Load Testing จาก CloudFormation กันครับ
ภาพด้านล่างคือโครงสร้างที่เราจะทำในบทความนี้ครับ
แต่อย่าพึ่งตกใจ! ทั้งหมดนี่ถูกเรียบเรียงไว้ใน CloudFormation Stack แล้ว แค่เราทำการสร้าง Stack ก็จะได้ Service ตามในภาพด้านบนเลยครับ
.
.
.
ก่อนอื่นให้เราทำการเข้าไปยังเว็บไซต์ต่อไปนี้
Distributed Load Testing on AWS | AWS Solutions | AWS Solutions Library
แล้วทำการคลิก Launch in AWS Console
หลังจากนั้นเราจะมาโผล่ที่หน้าต่าง AWS CloudFormation Console
ให้เรากด Next
เพื่อไปยังหน้าต่างต่อไป
- ชื่อ Stack ที่เรากำลังจะสร้าง
- Console Administrator คือ Load Testing Web Application Console ที่เรากำลังจะสร้างขึ้นโดย Stack ตัวนี้, username คือ ID ที่เราจะใช้ login ใน Console Administrator
ส่วน Console Administrator Email ให้ใส่ Email ที่มีอยู่จริง(จะมีข้อมูลส่งไปที่ Email ของเราในหัวข้อต่อไป) - ใส่ข้อมูล VPC ที่เราสร้างขึ้น(หัวข้อที่ 4) หรือจะใช้ Default VPC ก็น่าจะไม่มีปัญหาครับ
ในหน้าต่อไปที่เหลือ ไม่ต้องกรอกข้อมูลอะไรเพิ่มเติม ให้เราทำการกด Next
Next
แล้วกด Submit
เพื่อสร้าง CloudFormation Stack ได้เลยครับ
เมื่อสร้างเสร็จแล้วให้รอให้ Status: CREATE_COMPLETE
ครับ
เมื่อขึ้น Status: CREATE_COMPLETE
แล้วให้เราไปที่ Output เลยกดลิ้งค์ CloudFront ครับ
Username, Password ที่ใช้เข้าใช้งาน จะถูกยังไปยัง Email ที่เรากรอกในข้อมูล Stack ครับ
แล้วเราจะเข้ามาที่หน้าต่างของ Distributed Load Testing
ให้เราทำการกด CREATE TEST
โดยผมจะลองทำการสร้าง TEST ที่จะมีการเชื่อมต่อเข้าไป 200 Concurrency โดยที่จะค่อยๆเพิ่มจำนวนโดยจะจำนวนจะถึง 200 ภายใน 1 นาที
และจะเชื่อมต่อ(Hold)เป็นระยะเวลา 2 นาที ไปยัง http://mywebsite/test.php โดยใช้ GET HTTP Method ที่ไม่มีการปรับแต่งค่า (Optional)
ตามภาพด้านล่างนี้
ตั้งค่าเสร็จก็กด RUN NOW
เพื่อทำการทดสอบ
เราสามารถดูผลทดสอบโดยไปที่ DASHBOARD
แล้วกดดู Details
และนี่คือผลลัพท์ครับ
คำอธิบายของแต่ละ Parameter จะมีดังนี้ครับ
Test results - Distributed Load Testing on AWS
- Average response time - ค่าเฉลี่ย response time สำหรับ Request ทั้งหมดที่สร้างโดยการทดสอบ(มีหน่วยเป็นวินาที)
- Average latency - latency สำหรับ Request ทั้งหมดที่สร้างโดยการทดสอบ(มีหน่วยเป็นวินาที)
- Average connection time - เวลาเฉลี่ยที่ใช้ในการเชื่อมต่อ host สำหรับ Request ทั้งหมดที่สร้างโดยการทดสอบ(มีหน่วยเป็นวินาที)
- Average bandwidth - ค่าเฉลี่ย bandwidth สำหรับ Request ทั้งหมดที่สร้างโดยการทดสอบ
- Total count - จำนวน request ทั้งหมด
- Success count - จำนวน request ที่ success ทั้งหมด
- Error count - จำนวน request ที่ error ทั้งหมด
- Requests per second - ค่าเฉลี่ย Request ต่อวินาทีสำหรับ Request ทั้งหมดที่สร้างโดยการทดสอบ
- Percentile - percentile ของ response time สำหรับการทดสอบ, response time สูงสุดคือ 100%; response time ขั้นต่ำคือ 0%
ซึ่งจากผลลัพท์ภาพด้านบนที่ได้ จะเห็นว่าไม่มี Error count เกิดขึ้นและ Request Time ก็อยู่ในระดับที่ปกติดี
จึงสรุปได้ว่า EC2 instance t2.micro
ของผมสามารถรองรับเงื่อนไขด้านล่างนี้ได้
TEST ที่จะมีการเชื่อมต่อเข้าไป 200 Concurrency โดยที่จะค่อยๆเพิ่มจำนวนโดยจะจำนวนจะถึง 200 ภายใน 1 นาที และจะเชื่อมต่อ(Hold)เป็นระยะเวลา 2 นาที ไปยัง http://mywebsite/test.php โดยใช้ GET HTTP Method ที่ไม่มีการปรับแต่งค่า (Optional)
คราวนี้ผมจะทำการทดสอบอีกรอบ โดยเพิ่มจำนวน Concurrency จาก 200 ไปเป็น 1000 กันดูครับ
จากภาพด้านบนจะเห็นว่ายังไม่มี Error count แต่มี Percentile Response Time เพิ่มมากขึ้นเมื่อ 100% และ Requests Per Second มีจำนวนลดลง
คราวนี้ผมจะทำการทดสอบอีกรอบ โดยเพิ่มจำนวน Task Count จาก 1 ไปเป็น 5 และ Concurrency = 1000 กันดูครับ
จะเห็นได้ว่า 3 ส่วน 11 เกิด Error ไม่สามารถเข้าถึงเว็บไซต์ได้ ซึ่งหมายความได้ว่าEC2 instance t2.micro
ของผมไม่สามารถรองรับ Load ขนาดนี้ได้
เพิ่ม Reliability และ Performance Efficiency
จากหัวข้อด้านบน เราได้ทดสอบกับ EC2 instance ตัวเดียวไปแล้วตามภาพด้านล่างนี้
ในหัวข้อนี้ผมจะเปลี่ยนจากใช้ EC2 instance ตัวเดียวมาทำ server มาใช้ ALB + Auto Scaling เพื่อปรับขนาด Server ให้มีขนาดใหญ่ขึ้นอัตโนมัติตาม Load ที่เข้ามายัง Server
โดยหากจะพูดให้เห็นภาพก็คือ เมื่อมี Load เข้ามาเยอะๆ(CPU ของ instance ขึ้นสูง) ALB + Auto Scaling จะทำการสร้าง EC2 ตัวใหม่ขึ้นมาช่วยรับภาระ
ตามภาพด้านล่างนี้
(หากใครสนใจรายละเอียดเพิ่มเติมเกี่ยวกับ Auto Scaling สามารถตรวจสอบในหัวข้อ บทความที่เกี่ยวข้อง ที่ด้านท้ายบนความนี้ได้ครับ )
โดย Auto Scaling ที่ผมตั้งค่าในรอบนี้คือ
Desired capacity: 2
Minimum capacity: 2
Maximum capacity: 4
(เพิ่ม Instance เข้าไปขั้นต่ำเป็น 2 ตัว)
และตั้งค่า Scaling policy เป็นหากการใช้งาน CPU เกิน 35% ให้เพิ่มจำนวน instance เข้าไป (warm up 60 วิ)
เปลี่ยนการยิงเข้าไปผ่าน ALB แทน
ผลลัพท์ออกมาดีขึ้น แต่จากภาพยังบนยังมี Error อยู่บางส่วน
ผมคิดว่าการเพิ่ม Server แนวนอน(หลายๆตัว) อาจจะไม่เวิร์คในบางกรณี(Auto Scaling สร้างตัวใหม่ไม่ทัน) ผมเลยทำการเพิ่ม Server แนวตั้ง (t2.micro > t3.medium) ทั้งหมดแล้วทำการทดสอบอีกที
จะเห็นได้ว่าผลลัพท์ที่ได้ดีขึ้นกว่าครั้งที่แล้ว ซึ่งพอทำงานจริง การทดสอบนี้จะเสร็จที่จุดไหนอยู่ที่ความพอใจของผู้พัฒนาเลย
แต่สำหรับบทความสาธิตการทำงานของ Distributed Load Testing on AWS ก็ขอจบเพียงแค่นี้ (เพราะน่าจะเห็นภาพของการทำงานแล้ว)
(พอมาคิดดูแล้วการเพิ่มจำนวนเข้าถึงแค่ 1 นาที อาจจะไม่พอสำหรับการสร้าง instance ตัวใหม่ของ Auto Scaling ในส่วน RAMP UP อาจจะต้องเพิ่มระยะในนานขึ้น เพื่อดูการทำงาน)
สำหรับใครที่ทำตามบทความนี้ ก็อย่าลืมลบ Resource ที่สร้างขึ้นกันด้วย
โดยกด Delete ที่ Stack ได้เลย
บทความที่เกี่ยวข้อง
Distributed Load Testing on AWS | AWS Solutions | AWS Solutions Library
Distributed Load Testing on AWS - YouTube
วิธีติดตั้ง PHP 8.2 และ Apache ใน Amazon Linux 2023 บน EC2 | DevelopersIO
Cost - Distributed Load Testing on AWS
Test results - Distributed Load Testing on AWS
AWS CloudWatch คืออะไร? การแนะนำฟังก์ชันของ AWS CloudWatch ในปี 2023 | DevelopersIO
AWS CloudFormation คืออะไร? การแนะนำฟังก์ชันล่าสุดของ AWS | DevelopersIO
EC2 Instance ประเภท T คืออะไร? จะใช้งานได้ดีและถูกจริงๆเหรอ? | DevelopersIO
Amazon ALB (Application Load Balancer) คืออะไร? การแนะนำฟังก์ชันล่าสุดของ AWS | DevelopersIO
ทดลองใช้ Auto Scaling ใน EC2 | DevelopersIO
ทดลองใช้ ALB ของ EC2 เพื่อแบ่งการเชื่อมต่อ | DevelopersIO